<template>
  <div class="mmd-container">
    <!-- 顶部信息栏 -->
    <div class="info-panel">
      <div class="title">
        <h2>🎭 MMD Performance Demo</h2>
        <div class="subtitle">优化版本 - 青雀角色展示</div>
      </div>
      <div class="performance-stats">
        <div class="stat-item">
          <span class="stat-label">FPS:</span>
          <span class="stat-value" :class="{ 'low-fps': fps < 30, 'medium-fps': fps >= 30 && fps < 50 }">{{ fps }}</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">渲染时间:</span>
          <span class="stat-value">{{ renderTime }}ms</span>
        </div>
      </div>
    </div>

    <!-- 3D 渲染区域 -->
    <div ref="container" class="render-area"></div>

    <!-- 控制面板 -->
    <div class="control-panel">
      <div class="panel-header">
        <h3>🎮 控制面板</h3>
        <button @click="togglePanel" class="toggle-btn">
          {{ isPanelOpen ? '收起' : '展开' }}
        </button>
      </div>
      
      <div v-show="isPanelOpen" class="panel-content">
        <!-- 动画控制 -->
        <div class="control-section">
          <h4>🎬 动画控制</h4>
          <div class="animation-buttons">
            <button 
              v-for="(path, name) in animations" 
              :key="name"
              @click="switchAnimation(path, name)"
              :class="['anim-btn', { active: currentAnimation === name }]"
            >
              {{ name }}
            </button>
          </div>
        </div>

        <!-- 性能设置 -->
        <div class="control-section">
          <h4>⚡ 性能设置</h4>
          <div class="performance-controls">
            <div class="control-row">
              <label>目标FPS:</label>
              <select v-model="targetFPS" @change="updateFPSLimit">
                <option value="60">60 FPS</option>
                <option value="30">30 FPS</option>
                <option value="24">24 FPS</option>
              </select>
            </div>
            <div class="control-row">
              <label>阴影质量:</label>
              <select v-model="shadowQuality" @change="updateShadowQuality">
                <option value="high">高质量</option>
                <option value="medium">中等质量</option>
                <option value="low">低质量</option>
                <option value="off">关闭阴影</option>
              </select>
            </div>
            <div class="control-row">
              <label>抗锯齿:</label>
              <input type="checkbox" v-model="antialiasing" @change="updateAntialiasing">
            </div>
            <div class="control-row">
              <label>物理模拟:</label>
              <input type="checkbox" v-model="physicsEnabled" @change="updatePhysics">
            </div>
          </div>
        </div>

        <!-- 光照控制 -->
        <div class="control-section">
          <h4>💡 光照控制</h4>
          <div class="lighting-controls">
            <div class="control-row">
              <label>环境光强度:</label>
              <input type="range" v-model="lightSettings.ambient" min="0" max="1" step="0.1" @input="updateLighting">
            </div>
            <div class="control-row">
              <label>主光源强度:</label>
              <input type="range" v-model="lightSettings.main" min="0" max="3" step="0.1" @input="updateLighting">
            </div>
            <div class="control-row">
              <label>背景色调:</label>
              <input type="color" v-model="backgroundColor" @change="updateBackground">
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 加载指示器 -->
    <div v-if="isLoading" class="loading-overlay">
      <div class="loading-spinner">
        <div class="spinner"></div>
        <p>加载中... {{ loadingProgress }}%</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { MMDAnimationHelper } from "three/examples/jsm/animation/MMDAnimationHelper.js";
import { MMDLoader } from "three/examples/jsm/loaders/MMDLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import * as THREE from "three";
import { onMounted, reactive, ref, onUnmounted, nextTick } from "vue";

const container = ref(null);

// 响应式状态
const isPanelOpen = ref(true);
const isLoading = ref(true);
const loadingProgress = ref(0);
const fps = ref(60);
const renderTime = ref(0);
const targetFPS = ref(60);
const shadowQuality = ref('medium');
const antialiasing = ref(true);
const physicsEnabled = ref(true);
const backgroundColor = ref('#1a1a2e');
const currentAnimation = ref('TW动作');

// 光照设置
const lightSettings = reactive({
  ambient: 0.4,
  main: 1.2
});

// Three.js 核心对象
let scene, camera, renderer, clock;
let frameId;
let helper;
let modelMesh;
let loader;
let spotLight, ambientLight;
let controls;

// 性能优化相关
let lastFrameTime = 0;
let frameInterval = 1000 / 60; // 默认60FPS
let renderStartTime = 0;

// 动作配置
const animations = {
  'TW动作': '/move/tw.vmd',
  'Ayaka舞蹈': '/move/ayaka-dance.vmd'
};

// 性能监控
function startPerformanceMonitoring() {
  let frameCount = 0;
  let lastTime = performance.now();
  
  function updateFPS() {
    frameCount++;
    const currentTime = performance.now();
    
    if (currentTime - lastTime >= 1000) {
      fps.value = Math.round((frameCount * 1000) / (currentTime - lastTime));
      frameCount = 0;
      lastTime = currentTime;
    }
    
    requestAnimationFrame(updateFPS);
  }
  
  updateFPS();
}

// 优化的动画加载函数
async function loadAnimation(animationPath) {
  if (!modelMesh || isLoading.value) return;
  
  isLoading.value = true;
  loadingProgress.value = 0;
  
  try {
    // 暂停当前动画
    if (helper) {
      helper.remove(modelMesh);
    }
    
    // 创建新的helper实例
    helper = new MMDAnimationHelper({
      afterPhysics: physicsEnabled.value ? undefined : function() {}
    });
    
    // 异步加载动画
    await new Promise((resolve, reject) => {
      loader.loadAnimation(
        animationPath,
        modelMesh,
        function(animation) {
          loadingProgress.value = 100;
          
          helper.add(modelMesh, {
            animation: animation,
            physics: physicsEnabled.value
          });
          
          resolve();
        },
        function(progress) {
          if (progress.lengthComputable) {
            loadingProgress.value = Math.round((progress.loaded / progress.total) * 100);
          }
        },
        reject
      );
    });
    
  } catch (error) {
    console.error('加载动画出错:', error);
  } finally {
    isLoading.value = false;
  }
}

// 切换动画
function switchAnimation(path, name) {
  if (currentAnimation.value !== name) {
    currentAnimation.value = name;
    loadAnimation(path);
  }
}

// 更新FPS限制
function updateFPSLimit() {
  frameInterval = 1000 / parseInt(targetFPS.value);
}

// 更新阴影质量
function updateShadowQuality() {
  if (!renderer || !spotLight) return;
  
  const qualityMap = {
    high: { size: 2048, type: THREE.PCFSoftShadowMap },
    medium: { size: 1024, type: THREE.PCFShadowMap },
    low: { size: 512, type: THREE.BasicShadowMap },
    off: { size: 0, type: THREE.BasicShadowMap }
  };
  
  const quality = qualityMap[shadowQuality.value];
  
  if (shadowQuality.value === 'off') {
    renderer.shadowMap.enabled = false;
    spotLight.castShadow = false;
  } else {
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = quality.type;
    spotLight.castShadow = true;
    spotLight.shadow.mapSize.width = quality.size;
    spotLight.shadow.mapSize.height = quality.size;
  }
}

// 更新抗锯齿
function updateAntialiasing() {
  // 需要重新创建renderer来改变抗锯齿设置
  const oldRenderer = renderer;
  const newRenderer = new THREE.WebGLRenderer({ 
    antialias: antialiasing.value,
    alpha: false,
    powerPreference: "high-performance"
  });
  
  newRenderer.setSize(window.innerWidth, window.innerHeight);
  newRenderer.setClearColor(new THREE.Color(backgroundColor.value));
  newRenderer.shadowMap.enabled = shadowQuality.value !== 'off';
  updateShadowQuality();
  
  container.value.removeChild(oldRenderer.domElement);
  container.value.appendChild(newRenderer.domElement);
  
  renderer = newRenderer;
  oldRenderer.dispose();
  
  // 重新绑定控制器
  controls.dispose();
  controls = new OrbitControls(camera, renderer.domElement);
  controls.target.set(0, 10, 0);
  controls.enableDamping = true;
  controls.dampingFactor = 0.05;
  controls.update();
}

// 更新物理模拟
function updatePhysics() {
  if (helper && modelMesh) {
    helper.remove(modelMesh);
    helper.add(modelMesh, {
      animation: helper.meshes[0]?.animation,
      physics: physicsEnabled.value
    });
  }
}

// 更新光照
function updateLighting() {
  if (ambientLight) {
    ambientLight.intensity = lightSettings.ambient;
  }
  if (spotLight) {
    spotLight.intensity = lightSettings.main;
  }
}

// 更新背景色
function updateBackground() {
  if (renderer) {
    renderer.setClearColor(new THREE.Color(backgroundColor.value));
  }
}

// 切换面板显示
function togglePanel() {
  isPanelOpen.value = !isPanelOpen.value;
}

// 优化的渲染循环
function render(currentTime) {
  // FPS限制
  if (currentTime - lastFrameTime < frameInterval) {
    frameId = requestAnimationFrame(render);
    return;
  }
  
  renderStartTime = performance.now();
  
  // 更新控制器（如果启用了阻尼）
  controls.update();
  
  // 更新MMD动画
  if (helper) {
    helper.update(clock.getDelta());
  }
  
  // 渲染场景
  renderer.render(scene, camera);
  
  // 计算渲染时间
  renderTime.value = Math.round(performance.now() - renderStartTime);
  
  lastFrameTime = currentTime;
  frameId = requestAnimationFrame(render);
}

onMounted(async () => {
  const width = window.innerWidth;
  const height = window.innerHeight;
  
  // 初始化场景
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
  camera.position.set(0, 15, 30);
  
  // 创建优化的渲染器
  renderer = new THREE.WebGLRenderer({ 
    antialias: antialiasing.value,
    alpha: false,
    powerPreference: "high-performance"
  });
  renderer.setSize(width, height);
  renderer.setClearColor(new THREE.Color(backgroundColor.value));
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFShadowMap;
  
  clock = new THREE.Clock();
  loader = new MMDLoader();
  
  // 优化的光照设置
  ambientLight = new THREE.AmbientLight(0x404040, lightSettings.ambient);
  scene.add(ambientLight);
  
  spotLight = new THREE.SpotLight(0xffffff, lightSettings.main);
  spotLight.position.set(15, 25, 15);
  spotLight.distance = 100;
  spotLight.angle = Math.PI / 4;
  spotLight.penumbra = 0.3;
  spotLight.decay = 1;
  spotLight.castShadow = true;
  spotLight.shadow.mapSize.width = 1024;
  spotLight.shadow.mapSize.height = 1024;
  spotLight.shadow.camera.near = 0.5;
  spotLight.shadow.camera.far = 100;
  
  scene.add(spotLight);
  scene.add(spotLight.target);
  
  container.value.appendChild(renderer.domElement);
  
  // 优化的控制器设置
  controls = new OrbitControls(camera, renderer.domElement);
  controls.target.set(0, 10, 0);
  controls.enableDamping = true;
  controls.dampingFactor = 0.05;
  controls.maxDistance = 100;
  controls.minDistance = 10;
  controls.update();
  
  // 创建优化的地面
  const planeGeometry = new THREE.PlaneGeometry(50, 50, 1, 1);
  const planeMaterial = new THREE.MeshLambertMaterial({ 
    color: 0x2a2a2a,
    transparent: true,
    opacity: 0.8
  });
  const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
  planeMesh.rotation.x = -Math.PI / 2;
  planeMesh.receiveShadow = true;
  scene.add(planeMesh);
  
  // 初始化MMD助手
  helper = new MMDAnimationHelper();
  
  // 加载初始模型和动画
  try {
    await new Promise((resolve, reject) => {
      loader.loadWithAnimation(
        "/qque/青雀（分桦）.pmx",
        animations[currentAnimation.value],
        function onLoad(mmd) {
          modelMesh = mmd.mesh;
          
          // 优化模型设置
          modelMesh.castShadow = true;
          modelMesh.receiveShadow = true;
          
          helper.add(mmd.mesh, {
            animation: mmd.animation,
            physics: physicsEnabled.value
          });

          scene.add(mmd.mesh);
          
          // 调整聚光灯目标到模型
          spotLight.target.position.set(0, 10, 0);
          spotLight.target.updateMatrixWorld();
          
          isLoading.value = false;
          resolve();
        },
        function(progress) {
          if (progress.lengthComputable) {
            loadingProgress.value = Math.round((progress.loaded / progress.total) * 100);
          }
        },
        reject
      );
    });
  } catch (error) {
    console.error('加载初始模型出错:', error);
    isLoading.value = false;
  }
  
  // 启动性能监控
  startPerformanceMonitoring();
  
  // 启动渲染循环
  frameId = requestAnimationFrame(render);
  
  // 窗口大小调整处理
  window.addEventListener('resize', () => {
    const newWidth = window.innerWidth;
    const newHeight = window.innerHeight;
    
    camera.aspect = newWidth / newHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(newWidth, newHeight);
  });
});

onUnmounted(() => {
  if (frameId) {
    cancelAnimationFrame(frameId);
  }
  
  if (controls) {
    controls.dispose();
  }
  
  if (renderer) {
    renderer.dispose();
  }
  
  window.removeEventListener('resize', () => {});
});
</script>

<style scoped>
.mmd-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
  font-family: 'Microsoft YaHei', sans-serif;
  overflow: hidden;
}

.render-area {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* 顶部信息栏 */
.info-panel {
  position: absolute;
  top: 20px;
  left: 20px;
  right: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(10px);
  border-radius: 15px;
  padding: 15px 25px;
  z-index: 100;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.title h2 {
  margin: 0;
  color: #ffffff;
  font-size: 1.5em;
  font-weight: 700;
}

.subtitle {
  color: #64b5f6;
  font-size: 0.9em;
  margin-top: 5px;
}

.performance-stats {
  display: flex;
  gap: 20px;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.stat-label {
  color: #aaa;
  font-size: 0.8em;
  margin-bottom: 2px;
}

.stat-value {
  color: #4caf50;
  font-size: 1.2em;
  font-weight: bold;
}

.stat-value.medium-fps {
  color: #ff9800;
}

.stat-value.low-fps {
  color: #f44336;
}

/* 控制面板 */
.control-panel {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 320px;
  background: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(15px);
  border-radius: 15px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  overflow: hidden;
  z-index: 100;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background: rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.panel-header h3 {
  margin: 0;
  color: #ffffff;
  font-size: 1.1em;
}

.toggle-btn {
  background: #64b5f6;
  color: white;
  border: none;
  padding: 5px 12px;
  border-radius: 20px;
  cursor: pointer;
  font-size: 0.85em;
  transition: all 0.3s ease;
}

.toggle-btn:hover {
  background: #42a5f5;
  transform: translateY(-1px);
}

.panel-content {
  padding: 20px;
  max-height: 400px;
  overflow-y: auto;
}

.control-section {
  margin-bottom: 25px;
}

.control-section h4 {
  margin: 0 0 15px 0;
  color: #64b5f6;
  font-size: 1em;
  border-bottom: 1px solid rgba(100, 181, 246, 0.3);
  padding-bottom: 5px;
}

/* 动画按钮 */
.animation-buttons {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.anim-btn {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.2);
  padding: 8px 16px;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 0.9em;
}

.anim-btn:hover {
  background: rgba(100, 181, 246, 0.3);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(100, 181, 246, 0.3);
}

.anim-btn.active {
  background: #64b5f6;
  color: white;
  box-shadow: 0 4px 15px rgba(100, 181, 246, 0.4);
}

/* 控制行 */
.control-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.control-row label {
  color: #ffffff;
  font-size: 0.9em;
  flex: 1;
}

.control-row select,
.control-row input[type="range"],
.control-row input[type="color"] {
  flex: 1;
  max-width: 120px;
  margin-left: 10px;
}

.control-row select {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 5px;
  padding: 5px;
}

.control-row input[type="range"] {
  accent-color: #64b5f6;
}

.control-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: #64b5f6;
}

/* 加载指示器 */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.loading-spinner {
  text-align: center;
  color: #ffffff;
}

.spinner {
  width: 50px;
  height: 50px;
  border: 3px solid rgba(100, 181, 246, 0.3);
  border-top: 3px solid #64b5f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 20px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.loading-spinner p {
  font-size: 1.1em;
  margin: 0;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .info-panel {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .performance-stats {
    margin-top: 10px;
  }
  
  .control-panel {
    width: calc(100% - 40px);
    bottom: 10px;
    right: 20px;
    left: 20px;
  }
  
  .control-row {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .control-row select,
  .control-row input[type="range"],
  .control-row input[type="color"] {
    width: 100%;
    max-width: none;
    margin: 5px 0 0 0;
  }
}

/* 滚动条样式 */
.panel-content::-webkit-scrollbar {
  width: 6px;
}

.panel-content::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
}

.panel-content::-webkit-scrollbar-thumb {
  background: #64b5f6;
  border-radius: 3px;
}

.panel-content::-webkit-scrollbar-thumb:hover {
  background: #42a5f5;
}
</style>
